package com.djmw.mouse.shiro.web.filter.authz;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.util.WebUtils;

/**
 * 不同角色有各自的登录url，当访问未认证时，应根据所需的角色跳转到对应的登录url。
 * 为设置所需角色与对应的登录url的关系，重载shiro的角色权限filter。
 * 
 * @author leo
 */
public class RolesAuthorizationFilter extends org.apache.shiro.web.filter.authz.RolesAuthorizationFilter {
	private Map<String, String> loginUrls;

	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {

        Subject subject = getSubject(request, response);
        // If the subject isn't identified, redirect to login URL
        if (subject.getPrincipal() == null) {
            saveRequestAndRedirectToLogin(request, response, mappedValue);
        } else {
            // If subject is known but not authorized, redirect to the unauthorized URL if there is one
            // If no unauthorized URL is specified, just return an unauthorized HTTP status code
            String unauthorizedUrl = getUnauthorizedUrl();
            //SHIRO-142 - ensure that redirect _or_ error code occurs - both cannot happen due to response commit:
            if (StringUtils.hasText(unauthorizedUrl)) {
                WebUtils.issueRedirect(request, response, unauthorizedUrl);
            } else {
                WebUtils.toHttp(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
            }
        }
        return false;
    }

	private void saveRequestAndRedirectToLogin(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        saveRequest(request);
        redirectToLogin(request, response, mappedValue);
    }

	private void redirectToLogin(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        String loginUrl = getLoginUrl(mappedValue);
        WebUtils.issueRedirect(request, response, loginUrl);
    }

    public String getLoginUrl(Object mappedValue) {
        String[] rolesArray = (String[]) mappedValue;
        if (rolesArray == null || rolesArray.length == 0) {
            //no roles specified, so redirect to default login page.
            return getLoginUrl();
        }

        String loginUrl = getLoginUrls().get(rolesArray[0]);
        if (loginUrl != null && loginUrl.length() > 0) {
        	return loginUrl;
        } else {
        	return getLoginUrl();
        }
    }

	public Map<String, String> getLoginUrls() {
		return loginUrls;
	}

	public void setLoginUrls(Map<String, String> loginUrlMap) {
		this.loginUrls = loginUrlMap;
	}

}
